from functools import wraps
from datetime import datetime
import os

from flask import render_template, request, redirect, session
from flask import jsonify

from system_manage.flask_from import LoginForm
from system_manage.oa_system import oa_system
from system_manage.models import *
from system_manage import csrf



@oa_system.context_processor
def message():
    """
    添加中间件
    """
    result = {'g_name': "未登录"}
    if session.get('name'):
        p = Person.query.filter(Person.P_name == session.get('name')).first()
        p_i = p.Pe_P
        if p_i:  # 判断是否有昵称,有昵称显示昵称,没有则显示用户名
            result = {'g_name': p_i.nickname}
        else:
            result = {'g_name': p.P_name}
    return result


def set_password(pa):
    """
    对用户密码进行加密
    """
    md5 = hashlib.md5()  # import hashlib -- from system_manage.models import *
    md5.update(pa.encode())
    return md5.hexdigest()


def is_login(fun):
    """
    判断是否登陆(session技术)
    """

    @wraps(fun)  # from functools import wraps
    def inner(*args, **kwargs):
        name = session.get('name')  # from flask import render_template, request, redirect, session
        if name and Person.query.filter(Person.P_name == name):
            return fun(*args, **kwargs)
        else:
            return redirect('/')

    return inner

@csrf.exempt
@oa_system.route('/', methods=['GET', 'POST'])
def login():
    """
    用户登录
    """
    f = LoginForm()
    if request.method == 'POST':
        if f.validate_on_submit():  # from system_manage.flask_from import LoginForm
            data = request.form
            name = data.get('username')
            password = data.get('password')
            person = Person.query.filter(Person.P_name == name, Person.P_password == set_password(password)).first()
            if person:
                session['name'] = name  # 设置session校验信息
                return redirect('/oa_system/index/')
        else:
            errors = f.errors

    return render_template('login.html')


@oa_system.route('/index/')
@is_login
def index():
    """
    首页
    """
    N_list = News.query.filter().limit(4)  # 设置首页显示的新闻数量
    A_list = Person.query.filter(Person.P_name == session.get('name')).first().P_A[0:3]  # 设置首页显示的考勤数量
    return render_template('index.html', **locals())


@oa_system.route('/view/')
def view():
    """
    首页的KPI图 (ajax请求)
    """
    kpi = [i.kpi for i in Person.query.filter(Person.P_name == session.get('name')).first().P_K]
    for i in range(12 - len(kpi)):
        kpi.append(0)
    return jsonify({'kpi': kpi})


@oa_system.route('/log_out/')
def log_out():
    """
    退出系统
    """
    del session['name']
    return redirect('/oa_system/')


@oa_system.route('/news/')
@is_login
def news():
    """
    新闻管理页面
    """
    page = int(request.args.get("page", 1))
    news_list = News.query.filter().order_by(News.publish_time.desc()).paginate(page, 10)  # 分页
    return render_template('news.html', **locals())


def re_picture(filename):
    """
    处理图片的函数
    """
    path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'static')
    file_path = os.path.join('img', filename)
    save_path = os.path.join(path, file_path)
    return file_path, save_path


@oa_system.route('/add_news/', methods=['GET', 'POST'])
@is_login
def add_news():
    """
    添加新闻
    """
    if request.method == 'POST':
        # 保存文字和时间信息
        picture = request.files.get('picture')
        filename = picture.filename
        N = News()
        N.title = request.form.get('title')
        N.author = request.form.get('author')
        N.content = request.form.get('content')
        N.publish_time = datetime.now()
        # 处理图片信息
        if filename:
            file_path, save_path = re_picture(filename)
            picture.save(save_path)
            N.picture = file_path
        N.add()
        return redirect('/oa_system/news/')

    return render_template('add_news.html')


@oa_system.route('/news/<d>/')
@is_login
def detail_news(d):
    """
    新闻详细内容
    """
    main_news = News.query.filter(News.id == int(d)).first()
    return render_template('detail_news.html', **locals())


@oa_system.route('/delete_news/<t>/')
@is_login
def delete_news(t):
    """
    删除新闻
    """
    N = News
    d_news = N.query.filter(News.id == int(t)).all()[0]
    d_news.delete()
    return redirect('/oa_system/news/')


@oa_system.route('/edit_news/<s>/', methods=['POST', 'GET'])
@is_login
def edit_news(s):
    """
    编辑新闻
    """
    N = News()
    M_news = N.query.filter(News.id == int(s)).all()[0]
    if request.method == 'POST':
        # 保存文字和时间信息
        picture = request.files.get('picture')
        filename = picture.filename
        M_news.title = request.form.get('title')
        M_news.author = request.form.get('author')
        M_news.content = request.form.get('content')
        M_news.publish_time = datetime.now()
        # 处理图片信息
        if filename != '':
            file_path, save_path = re_picture(filename)
            picture.save(save_path)
            M_news.picture = file_path
        M_news.update()
        return redirect('/oa_system/news/')
    return render_template('edit_news.html', **locals())


@oa_system.route('/permission/')
@is_login
def permission():
    """
    权限管理-列表页
    """
    per_list = Permission.query.all()
    return render_template('permission.html', **locals())


def permission_charge(n):
    """
    判断是否具有权限
    """
    value = False
    permission_list = [p.id for p in
                       Person.query.filter(Person.P_name == session.get('name')).first().Pe_P.per_P.pos_permission]
    if n in permission_list:
        value = True
    return value


@oa_system.app_template_global('show')
@is_login
def show():
    """
    下发权限
    """
    result = {'permission': permission_charge(1),
              'news': permission_charge(2),
              'attendance': permission_charge(3),
              'department': permission_charge(4),
              'person': permission_charge(5),
              }
    return result


@oa_system.route('/add_permission/', methods=['GET', 'POST'])
@is_login
def add_permission():
    """
    添加权限
    """
    if request.method == 'POST':
        per = Permission()
        per.per_name = request.form.get('name')
        per.pe_des = request.form.get('description')
        per.add()
        return redirect('/oa_system/permission/')
    return render_template('add_permission.html')


@oa_system.route('/edit_permission/<t>/', methods=['GET', 'POST'])
def edit_permission(t):
    """
    修改权限
    """
    per = Permission.query.filter(Permission.id == t).all()[0]
    if request.method == "POST":
        per.per_name = request.form.get('name')
        per.pe_des = request.form.get('description')
        per.update()
        return redirect('/oa_system/permission/')
    return render_template('edit_permission.html', **locals())


@oa_system.route('/delete_permission/<t>/')
def delete_permission(t):
    """
    删除权限
    """
    per = Permission.query.get(t).first()
    per.delete()
    return redirect('/oa_system/permission/')


@oa_system.route('/position_permission/<t>/', methods=['GET', 'POST'])
def position_permission(t):
    """
     权限对应职位
    """
    pos_list = Position.query.all()
    P = Permission.query.get(t)
    if request.method == 'POST':
        rest = request.form.getlist('name')
        Permission.query.get(t).permission_pos = [Position.query.filter(Position.Pos_name == i).first() for i in rest]
        P.add()
    d = P.permission_pos
    return render_template('position_permission.html', **locals())


@oa_system.route('/attendance_me/', methods=['GET', 'POST'])
@is_login
def attendance():
    """
    考勤管理-个人考勤
    """
    name = session.get('name')
    p = Person.query.filter(Person.P_name == name).first()
    att_me = p.P_A
    Dep = p.Pe_P.P_D  # 查到员工所在部门
    Viewers = [i.P_Per[0] for i in Dep.D_Pos if i.level == p.Pe_P.per_P.level + 1 and i.P_Per]  # 查到员工同部门直管领导
    return render_template('attendance_me.html', **locals())


@oa_system.route('/attendance_me_add/', methods=['GET', 'POST'])
@is_login
def add_attendance_me():
    """
    个人考勤管理_添加考勤
    """
    if request.method == 'POST':
        att = Attendance()
        att.cause = request.form.get('reason')
        att.a_length = request.form.get('day')
        att.start_time = request.form.get('start')
        att.end_time = request.form.get('end')
        att.type = request.form.get('type')
        att.Examiners = request.form.get('view')
        att.add()
        att = Attendance.query.all()[-1]
        name = session.get('name')
        p = Person.query.filter(Person.P_name == name).first()
        p.P_A.append(att)
        p.add()
        return redirect('/oa_system/attendance_me/')
    return render_template('attendance_me.html')


@oa_system.route('/attendance_subordinate/')
@is_login
def attendance_subordinate():
    """
    下属考勤
    """
    attendance_list = Attendance.query.filter(Attendance.Examiners == session.get('name'), ).all()  # 获取下属的全部考勤
    return render_template('attendance_subordinate.html', **locals())


@oa_system.route('/set_att/<t>/')
def att_charge(t):
    """
    考勤状态设置
    """
    order = request.args.get('order')
    att = Attendance.query.get(int(t))
    if order == '2':
        att.status = '通过'
        att.update()
        return redirect('/oa_system/attendance_subordinate/')
    elif order == '3':
        att.update()
        att.status = '驳回'
        return redirect('/oa_system/attendance_subordinate/')
    elif order == '1':
        att.status = '撤销'
        att.update()
        return redirect('/oa_system/attendance_me/')


@oa_system.route('/person/', methods=['GET', 'POST'])
@is_login
def person():
    """
    职员管理-列表页
    """
    d_list = Department.query.filter().all()
    page = int(request.args.get("page", 1))
    person_list = PersonInfo.query.filter().paginate(page, 10)
    return render_template('person.html', **locals())


@oa_system.route('/detail_person/<t>/')
@is_login
def detail_person(t):
    """
    职员管理-详情
    """
    p_i = PersonInfo.query.get(int(t))
    p = p_i.p_pe
    return render_template('detail_person.html', **locals())


@oa_system.route('/d_p/')
def show_position():
    """
    职员管理部门-职位联动(ajax请求)
    """
    rest = []
    s = int(request.args.get('t'))
    if s:
        p_list = Department.query.get(s).D_Pos
        rest = [{'id': i.id, 'pos_name': i.Pos_name} for i in p_list]
    return jsonify(rest)


@oa_system.route('/edit_person/<t>/', methods=['GET', 'POST'])
@is_login
def edit_person(t):
    """
    职员管理-编辑
    """
    p_i = PersonInfo.query.get(int(t))
    p = p_i.p_pe
    pos_list = Position().query.all()
    if request.method == 'POST':
        p.P_name = request.form.get('username')
        p.P_password = set_password(request.form.get('password'))
        p.update()
        p_i.nickname = request.form.get('nickname')
        p_i.sex = request.form.get('gender')
        p_i.age = request.form.get('age')
        p_i.phone = request.form.get('phone')
        p_i.email = request.form.get('email')
        picture = request.files.get('photo')
        if picture:
            filename = picture.name
            file_path, save_path = re_picture(filename)
            picture.save(save_path)
            p_i.p_picture = file_path
        p_i.address = request.form.get('address')
        p_i.per_pos = request.form.get('position_id')
        p_i.update()
        return redirect('/oa_system/person/')
    return render_template('edit_person.html', **locals())


@oa_system.route('/add_person/', methods=['GET', 'POST'])
@is_login
def add_person():
    """
    职员管理-添加
    """
    department_list = Department.query.all()
    if request.method == 'POST':
        p = Person()
        p.P_name = request.form.get('username')
        p.P_password = set_password(request.form.get('password'))
        p.add()
        p_i = PersonInfo()
        p_i.nickname = request.form.get('nickname')
        p_i.sex = request.form.get('gender')
        p_i.age = request.form.get('age')
        p_i.phone = request.form.get('phone')
        p_i.email = request.form.get('email')
        picture = request.files.get('photo')
        if picture:
            filename = picture.name
            file_path, save_path = re_picture(filename)
            picture.save(save_path)
            p_i.p_picture = file_path
        p_i.address = request.form.get('address')
        p_i.per_pos = request.form.get('position_id')
        p_i.per_per = db.session.query(func.max(Person.id)).filter().first()[0]
        p_i.per_de = request.form.get('department_id')
        p_i.add()
        return redirect('/oa_system/person/')
    return render_template('add_person.html', **locals())


@oa_system.route('/delete_person/<t>/', methods=['GET', 'POST'])
@is_login
def delete_person(t):
    """
    职员管理删除个人信息
    """
    p_i = PersonInfo.query.get(int(t))
    p_i.p_pe.delete()
    p_i.delete()
    return redirect('/oa_system/person/')


@oa_system.route('/person/<t>/')
@is_login
def select_d(t):
    """
    职员管理-选择部门
    """
    page = int(request.args.get("page", 1))
    d_list = Department.query.filter().all()
    person_list = PersonInfo.query.filter(
        PersonInfo.nickname.in_(
            [i.nickname for i in Department.query.filter(Department.D_name == t).first().D_P])).paginate(
        page, 10)
    return render_template('person.html', **locals())


@oa_system.route('/search_user/', methods=['GET', 'POST'])
def search_user():
    """
    职员管理搜索职员
    """
    d_list = Department.query.filter().all()
    page = int(request.args.get("page", 1))
    person_list = PersonInfo.query.filter().paginate(page, 10)
    if request.method == 'POST':
        name = request.form.get('person_username')
        if name:
            n_name = Person.query.filter(Person.P_name == name).first().Pe_P.nickname
            person_list = PersonInfo.query.filter(
                PersonInfo.nickname == n_name).paginate(page, 10)
    return render_template('person.html', **locals())


@oa_system.route('/department/')
@is_login
def department():
    """
    部门管理
    """
    D_list = Department.query.filter().all()
    return render_template('department.html', **locals())


@oa_system.route('/add_department/', methods=['GET', 'POST'])
@is_login
def add_department():
    """
    部门管理-添加部门
    """
    if request.method == 'POST':
        d = Department()
        d.D_name = request.form.get('name')
        d.D_des = request.form.get('description')
        d.add()
        return redirect('/oa_system/department/')
    return render_template('add_department.html')


@oa_system.route('/edit_department/<t>/', methods=['GET', 'POST'])
@is_login
def edit_department(t):
    """
    部门管理-编辑部门
    """
    main_d = Department.query.filter(Department.id == t).first()
    if request.method == 'POST':
        main_d.D_name = request.form.get('name')
        main_d.D_des = request.form.get('description')
        main_d.update()
        return redirect('/department/')
    return render_template('edit_department.html', **locals())


@oa_system.route('/delete_department/<t>/', methods=['GET', 'POST'])
@is_login
def delete_department(t):
    """
    部门管理-删除部门
    """
    main_d = Department.query.filter(Department.id == t).first()
    main_d.delete()
    return redirect('/department/')


@oa_system.route('/p_department/<t>/', methods=['POST', 'GET'])
@is_login
def p_department(t):
    """
    部门管理-查看职位与添加职位
    """
    D = Department.query.get(t)
    pos_list = D.D_Pos
    if request.method == "POST":
        name = request.form.get('name')
        level = request.form.get('level')
        pos = Position()
        pos.Pos_name = name
        pos.Pos_des = name
        pos.level = level
        pos.add()
        pos_list.append(pos)
        pos.add()
    return render_template('position.html', **locals())


@oa_system.route('/des_position/<t>/')
@is_login
def des_position(t):
    """
    编辑职位
    """
    return render_template('position.html', **locals())


@oa_system.route('/profile/')
@is_login
def profile():
    """
    个人中心
    """
    p = Person.query.filter(Person.P_name == session.get('name')).first()
    p_i = p.Pe_P
    # kpi_list = [i.kpi for i in p.P_K]
    # kpi = sum(kpi_list) / len(kpi_list)
    return render_template('profile.html', **locals())
